        TITL DAI FIRMWARE 0E401-0E601  V1.0  Rev.1
        ORG   :E401
*
*
*
************************
* RUN basiccmd RESTORE *
************************
*
RREST   LHLD  :029F     Get startaddr. textbuf
        SHLD  :0124     Store it in DATAP
        XRA   A
        DCR   A
        JMP   :E452     Set DATAQ=FF
*
*****************
* RUN RANDOMISE *
*****************
*
* Returns a hardware random number 0 < R < 1.
*
* Exit: BC preserved. AFDEHL corrupted.
*       Result in MACC.
*
RRAND   PUSH  B
        LXI   H,:FD00   Addr PORI
        CALL  :D65F     BC=0, E=0, #40 or #80
        MVI   D,:01
*
RMI10   LDA   :0293     Get RNDLY (0 by C72E)
        CALL  :D658     Delay, A=M XOR E
        RLC
        RLC
 REM
* Now CY is 0 if E=#40 and CY = bit 6 of FD00
* (hardware random) if E=0 or E=#80.
 REM
RMI20   MOV   A,D
        RAL             RAL D
        MOV   D,A
        MOV   A,C
        RAL             RAL C
        MOV   C,A
        MOV   A,B
        RAL             RAL B
        MOV   B,A
        ORA   A
        JP    :E415     Again if B<#80 (must be
 REM normalised FPT nr)
 REM
* Result in MACC:
 REM
        MVI   A,:01     Set exp.byte for 1 < R < 2
        RST   4         Copy A,B,C,D to MACC
        DATA  :12
        LXI   H,:D0F1   Addr FPT(-1)
        RST   4         Add -1 to MACC
        DATA  :00       Now: 0 < R < 1
        POP   B
        ORA   A         No special action
        RET
*
*
******************
* cont. of 0E3DC *
******************
*
MPT36   INX   H
        MOV   A,M       Get length dataline
        STA   :0134     Store it in EFECT
        INX   H         Pnts to start data bytes
        SHLD  :0132     Startaddr string in EFEPT
        NOP
        NOP
        POP   H
        POP   D
        MVI   E,:00
        POP   PSW
        RET
*
**************************
* PREPARE GETTING INPUTS *
**************************
*
MPT5A   SHLD  :011D     Store SP+2 in ERSSP
        MVI   A,:FF
        STA   :0117     Set flag for running inputs
        JMP   :E3D0     Print '?', input a textline
*
******************
* cont. of 0E401 *
******************
*
MPT32   STA   :0123     Save offset next char to
        RET             encode
*
        DATA  :FF
        DATA  :FF
        DATA  :FF
        DATA  :FF
*
********************
* RUN basiccmd LET *
********************
*
* Valid as direct command or in program. Computes
* variable pointer or variable reference and
* checks type. 'LET' can be explicitly or
* implicitly given.
*
* Entry: BC: Points to program line.
* Exit:  BC: Updated.
*        A:  Type of variable.
*        FDEHL corrupted.
*
*RLETX
RLETI   CALL  :E963     Get varptr in HL, T/L in A
        ANI   :30       Type only
        PUSH  PSW       Save type
        CPI   :20       String type?
        JNZ   :E494     Jump if INT/FPT
 REM
* If string type:
 REM
RLT10   PUSH  H         Save varptr
        MOV   A,M       )
        INX   H         )
        MOV   H,M       ) Addr string in HL
        MOV   L,A       
        XTHL            ) Save stringaddr
        PUSH  H         ) and varptr
        CALL  :E79D     Get value being assigned
        MOV   A,E       Get status
        CPI   :02
        JZ    :E47F     Jump if temp on heap
        MOV   A,M       Get string length
        XCHG
        CALL  :D18B     Get place in heap for string
        PUSH  H
        CALL  :D172     Transfer string into heap
        POP   H
RLT20   XCHG            Pntr to string in DE
        POP   H         Pntr to variable in HL
        MOV   M,E       ) Stringpntr in variable
        INX   H         )
        MOV   M,D       )
 REM
* Entry from scratch:
 REM
RLT25   LHLD  :029F     Get startaddr. textbuf
        XCHG            in DE
        POP   H         Get pntr old value
        MOV   A,H
        ORA   L
        CNZ   :DE14     If <>0: Test if on heap
        CC    :D187     Then clear string in heap
        JMP   :E4B2     Ready
 REM
* If FPT/INT type:
 REM
RLT30   PUSH  H
        CALL  :E819     Eval numeric arguments
        MOV   A,H
        ORA   L
        JNZ   :E4A3     Copy num expr if not in MACC
        POP   H
        RST   4         Copy MACC to variable
        DATA  :0F
        JMP   :E4B2     Ready
 REM
* If just constant or variable:
 REM
RLT50   POP   D         Get pntr to variable
        PUSH  D
        PUSH  B
        MVI   B,:04     Nr of bytes
RLT60   MOV   A,M       Get byte
        STAX  D         Store it in variable
        INX   H
        INX   D
        DCR   B         Decr byte count
        JNZ   :E4A8     Next byte if not ready
        POP   B
        POP   H
 REM
* Ready:
 REM
RLT90   POP   PSW
        RET
 REM
* Entry from READ/INPUT for FPT/INT:
 REM
RLT70   PUSH  PSW
        JMP   :E494     Value to variable
 REM
* Entry from READ/INPUT for STR:
 REM
RLT80   PUSH  PSW
        JMP   :E465     Stringvalue to variable
*
**********************
* RUN basiccmd SOUND *
**********************
*
* Formats: SOUND <CHAN><ENV><VOL><TG><FREQ>.
*          SOUND <CHAN> OFF.
*          SOUND OFF.
*
* Entry: BC: Points to program line.
* Exit:  BC updated, AFDEHL corrupted.
*
RSOUND  LDAX  B         Get 1st expr.
        CPI   :FF       Is it sound OFF?
        JZ    :E501     Then turn all sound off
        MVI   A,:02
        CALL  :E743     Get channelnr (0,1,2)
        LXI   H,:01C2   Startaddr SCB0
        LXI   D,:000E   Length SCB
        PUSH  PSW       Save channelnr
SND10   DCR   A
        JM    :E4D6     If chan.0 or ready
        DAD   D         Absolute addr SCB in HL
        JMP   :E4CE     If chan.2
SND20   POP   D         Channelnr in D
        CALL  :E51F     Set up SCB <ENV><VOL>
        JC    :E4FC     If channel to be OFF
        MVI   A,:03
        CALL  :E743     Get <TG>
        PUSH  PSW
        ANI   :01       Tremoloflag only
        MOV   M,A       Into SCB
        INX   H
        NOP
        NOP
        POP   PSW       Restore <TG>
        ANI   :02       Glissandoflag only
        RAR
        INR   A
        INX   H         1 free byte
        MOV   M,A       Glissandoflag in SCB
        INX   H         )
        INX   H         ) Ignore current period
        INX   H         )
        PUSH  H         Save pntr to reqd period
        CALL  :E6F8     Get <period>
        XCHG            in DE
        POP   H
        MOV   M,E       ) Reqd period in SCB
        INX   H         )
        MOV   M,D       )
SND70   CALL  :D996     Enable sound interrupts
        ORA   A         No special action
        RET
 REM
* If SOUND OFF:
 REM
SND80   INX   B
        CALL  :D98F     Disable sound interrupts
        PUSH  B
        CALL  :D8A6     Stop oscillators
        POP   B
        ORA   A         No special action
        RET
*
**********************
* RUN basiccmd NOISE *
**********************
*
* Sets up a noise control block.
* Formats: NOISE <ENV><VOL>.
*          NOISE OFF.
*
* Entry: BC: Points to expression.
* Exit:  Noise off: BC updated, DE preserved,
*                   AFHL corrupted.
*        Noise on:  BC updated, AFDEHL corrupted.
*
RNOISE  LXI   H,:01EC   Startaddr NCB
        MVI   D,:03     Channelnr.3
        CALL  :E51F     Set up NCB
        JC    :E4FC     If channel to be off
        MVI   M,:00     No tremolo
        INX   H
        MVI   M,:00     Current volume = 0
        JMP   :E4FC     Enable sound interrupts
*
****************
* SET ENVELOPE *
****************
*
* Sets up a sound or noise control block for
* a channel.
*
* Entry: D:  Channelnumber (0,1,2 or 3).
*        BC: Points to programline.
*        HL: Points to startaddr SCB/NCB.
* Exit:  If sound/noise off (CY=1):
*        FF in 1st byte of SCB/NCB.
*            HL: points to 1st byte SCB/NCB.
*            BC: points to 2nd byte SCB/NCB.
*            DE preserved, AF corrupted.
*        If sound/noise on (CY=0):
*        00 in 1st byte SCB/NCB.
*            HL: Points after free byte.
*            DE: Envelopeaddr +1.
*            BC: Points beyond volume.
*            AF: corrupted.
*
SNGEV   CALL  :D98F     Disable sound interrupts
        MVI   M,:00     00 in 1st byte SCB/NCB
        LDAX  B         Get 1st byte from progr.line
        CPI   :FF
        JZ    :E552     Jump if channel to be off
 REM
* If channel on:
 REM
        INX   H         Pntr to next byte of block
        PUSH  H         Save pntr
        MVI   A,:01
        CALL  :E743     Get envelopenr in A (0,1)
        LXI   H,:01F5   Addr envelope area
        RRC
        RRC
        MOV   E,A       DE=64*A
        MVI   D,:00
        DAD   D         Add offset for env area
        XCHG            Pntr to envelope in DE
        POP   H         Get input pntr SCB/NCB
        MOV   M,E       ) Envelope addr in block
        INX   H         )
        MOV   M,D       )
        INX   H
        INX   D
        MOV   M,E       ) Env addr +1 in block
        INX   H         )
        MOV   M,D       )
        INX   H
        MVI   A,:0F
        CALL  :E743     Get volume multiplier in
 REM A (0-15)
        RLC             )
        RLC             ) *8
        RLC             )
        MOV   M,A       Vol.*8 in block
        INX   H         Pntr to basic volume
        INX   H         Pntr to tremoloflag
        ORA   A         Return 'channel on'
        RET
 REM
* If channel to be off:
 REM
SNG10   INX   B
        DCR   M         FF in 1st byte SCB/NCB
        MOV   A,D       Get channelnr
        CPI   :03
        JZ    :E563     Jump if noisechannel
        RRC             ) Find disable data for
        RRC             ) chan. 0-2
        ORI   :36       )
        STA   :FC06     Load sound cmd word
        STC             Return 'channel off'
        RET
 REM
* If noise to be off:
 REM
SNG20   LDA   :0295     Get volume osc.2 + noise
        ANI   :0F       Vol. noise = 0
        STA   :0295     Update POR1M
        STA   :FD05     and POR1
        STC             Return 'channel off'
        RET
*
*
*************************
* RUN basiccmd ENVELOPE *
*************************
*
* Load envelope table 0 or 1 with data.
* Formats: ENVELOPE <ENV> (<V>,<T>;) <V>,<T> FF.
*          ENVELOPE <ENV> (<V>,<T>;) <V>.
*
RENV    MVI   A,:01
        CALL  :E743     Get envelope number (0,1)
        RRC
        RRC
        MOV   E,A       ) Offset for env addr
        MVI   D,:00     )
        LXI   H,:01F5   Addr env storage area
        DAD   D         Startaddr table in HL
        MVI   M,:00     00 in 1st field
        INX   H
        LDAX  B         Get length of expr
        INX   B
        INR   A
        MOV   D,A       Nr of complete entries in D
REN10   DCR   D
        JZ    :E59D     If all entries done
        MVI   A,:10
        CALL  :E743     Get volume (0-16)
        MOV   M,A       Into env table
        INX   H
        CALL  :E71D     Get time
        SUI   :01       Min. value is 1
        JC    :DA15     Run error 'NUMBER OUT OF
 REM RANGE' if time=0
        MOV   M,A       Time into env table
        INX   H
        JMP   :E585     Next <V>,<T>
REN15   MVI   M,:FF     FF as last in env table
        LDAX  B         Get last expr
        INX   B
        CPI   :FF       End marker?
        JZ    :E5B0     Then quit
        DCX   B
        MVI   A,:10
        CALL  :E743     Get final volume <V>
        MOV   M,A       <V> into env table
        INX   H
        MVI   M,:FF     Time = forever
REN20   ORA   A         No special action
        RET
*
***********************
* RUN basiccmd CURSOR *
***********************
*
RCURS   CALL  :E5F3     Evaluate coordinate
        MOV   H,A       Y-coord in H
        RST   5         Set cursor position
        DATA  :09
        JMP   :E5C9     Evt run screen error
*
*********************
* RUN basiccmd MODE *
*********************
*
* Entry: BC: Points to program line.
*
RMODE   LDAX  B         Get reqd mode in A
        INX   B
        JMP   :CEB5     Change screen mode
*
L0E99   RET
*
********************
* RUN basiccmd DOT *
********************
*
RDOT    CALL  :E5F9     Eval dot addr + colour
        PUSH  B
        MOV   C,E       Colour in C
        RST   5         Draw dot on screen
        DATA  :1E
RDT10   POP   B
RDT20   JC    :E602     Jump if screen error
        ORA   A         No special action
        RET
*
*********************
* RUN basiccmd DRAW *
*********************
*
RDRAW   CALL  :E5E0     Eval begin/end addr +
 REM colour
        XTHL
        RST   5         Draw a line on screen
        DATA  :21
        JMP   :E5C8     Evt. run screen error
*
*********************
* RUN basiccmd FILL *
*********************
*
RFILL   CALL  :E5E0     Eval coordinates, colour
        XTHL
        RST   5         Fill a rectangular area
        DATA  :24
        JMP   :E5C8     Evt run screen error
*
***********************************
* EVALUATE 2 COORDINATES + COLOUR *
***********************************
*
R2COC   CALL  :E5F3     Get 1st coordinate
        XTHL            X-coord on stack
        PUSH  H
        MOV   E,A       Y-coord in E
        CALL  :E5F3     Get 2nd coordinate,
 REM x-coord in HL
        MOV   D,A       Y-coord in D
        CALL  :E5FD     Get colour in A
        PUSH  B
        PUSH  D
        XCHG
        POP   B
        POP   H
        RET
*
***********************
* EVALUATE COORDINATE *
***********************
*
RCOOR   CALL  :E6F8     Get x-coord in HL
        JMP   :E71D     Get y-coord in A
*
********************************
* EVALUATE COORDINATE + COLOUR *
********************************
*
RCOCO   CALL  :E5F3     Get x-coord in HL
        MOV   E,A       Y-coord in E
RCOL    MVI   A,:17
        JMP   :E743     Get colour (0-23) in A
*
*
*
        UNL
RLETX   EQU RLETI
        LST
        END
